import GlobalConfig from '@/config/global';
import { getCachedPublicKey, getPublicKeyWithSig } from '@/contactLogic/pubkey.js';
import { ethers, Wallet, BigNumberish, Contract, BigNumber } from 'ethers'
import erc20 from '../constants/abis/erc20.json'
import staking from '../constants/abis/staking.json'
import store from '../store/index'

// /**
//  * @SCT合约地址
//  */
// const contractAddress = '0xa4B068aD60766E20283C0424C1F543E45100cFE3'

// /**
//  * @质押合约地址
//  */
// const pledgeContractAddress = '0xEC52e76571950da8dD20ecf1b065C6699164BD58'



// /**
//  * @SCT合约地址 --正式
//  */
//  let contractAddress = '0x405e7454e71aefe8897438adc08e3f3e6d49dfc1'

//  /**
//   * @质押合约地址  -- 正式
//   */
//  let pledgeContractAddress = '0xd7ae0a202608fA8F37d25706C06b1eE8E4d44D75'



const provider = new ethers.providers.Web3Provider(window.ethereum)

export async function cachedPublicKey(_this, ethAddress) {
    var cachedPubkey = await getCachedPublicKey(ethAddress)
    if (cachedPubkey) {
        _this.$store.commit('ethpublickey', cachedPubkey)
    }
}

export async function publicKeyWithSig(_this, ethAddress) {
    var pubkey = await getPublicKeyWithSig(ethAddress)
    if (pubkey) {
        _this.$store.commit('ethpublickey', pubkey)
    }
    return pubkey
}

export async function switchNetWork(_this, toChainId) {

    const chainData = GlobalConfig.ChainList.find(item => item.chainId === toChainId)
    if (!chainData) {
        throw new Error('current chain not support yet')
    }

    var chainIdHex = chainData.chainIdHex
    var chainConfig = chainData.config

    try {
        var res = await window.ethereum
            .request({ method: 'wallet_switchEthereumChain', params: [{ chainId: chainIdHex }] })
            .then(() => {
                return true
            })
            .catch(async e => {
                switch (e.code) {
                    case 4902:
                    case -32603:
                        if (!chainConfig) throw new Error('Unkonw chain config')
                        var addRes = await window.ethereum
                            .request({ method: 'wallet_addEthereumChain', params: [chainConfig] })
                            .then(() => {
                                return true
                            })
                            .catch(error => {
                                throw error
                            })
                        return addRes
                    default:
                        throw e
                }
            })

        _this.$store.commit('changeEthChainID', toChainId)

        return res
    } catch (e) {
        throw e
    }
}

export async function connectWallet(_this) {

    const res = await window.ethereum.enable()
    _this.$store.commit('changeEthAddress', res[0])

    const chainId = await window.ethereum
        .request({ method: 'eth_chainId' })
        .then(chainId => chainId);

    if (chainId != GlobalConfig.DefaultChainId) {
        await switchNetWork(_this, GlobalConfig.DefaultChainId)
    }
}

/** @千位分隔 */
export function numFormat(num) {
    num = num.toString().split(".");  // 分隔小数点
    var arr = num[0].split("").reverse();  // 转换成字符数组并且倒序排列
    var res = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        if (i % 3 === 0 && i !== 0) {
            res.push(",");   // 添加分隔符
        }
        res.push(arr[i]);
    }
    res.reverse(); // 再次倒序成为正确的顺序
    if (num[1]) {  // 如果有小数的话添加小数部分
        res = res.join("").concat("." + num[1]);
    } else {
        res = res.join("");
    }
    return res;
}

/**
 * @初始化Erc20合约对象
 */
export const InitErc20Contract = () => {
    
    const contractAddress = store.state.contract.contractAddress
    const CONTRACT = new ethers.Contract(contractAddress, erc20, provider);
    return CONTRACT
}



/**
 * @初始化质押合约对象
 */
export const InitPledgeContract = () => {
    const pledgeContractAddress = store.state.contract.pledgeContractAddress
    const CONTRACT = new ethers.Contract(pledgeContractAddress, staking, provider);
    return CONTRACT
}

/**
 * @初始化SCT合约对象Signer
 */
export const InitContractSigner = () => {
    const pledgeContractAddress = store.state.contract.pledgeContractAddress
    const CONTRACT = new ethers.Contract(pledgeContractAddress, staking, provider.getSigner());
    return CONTRACT
}

/**
 * @初始化质押合约对象Signer
 */
export const InitPledgeContractSigner = () => {
    const pledgeContractAddress = store.state.contract.pledgeContractAddress
    const CONTRACT = new ethers.Contract(pledgeContractAddress, staking, provider.getSigner());
    return CONTRACT
}


/**
 * @hex转换string
 * @param _hex 需要转换的BigNumber
 * @param ascii 转换进制
 */

export function BigNumberToString(_hex, ascii) {
    return ethers.utils.formatUnits(BigNumber.from(_hex), ascii)
}

/**
 * @查询合约余额
 * @param address 获取余额的公钥地址
 */

export const getBalanceOf = async (address) => {

    //连接合约
    const Contract = InitErc20Contract()
    //获取合约余额
    const balance = await Contract.balanceOf(address);
    const formattedBalance = BigNumberToString(balance, 18)
    console.log(formattedBalance);
    return formattedBalance
}

/**
 * @开始质押
 * @param address 消费者地址
 */

export const beginPledge = async (pond, address, balanceAllowance) => {
    try {
        const pledgeContractAddress = store.state.contract.pledgeContractAddress
        //初始化erc20合约
        const ercContract = InitErc20Contract();

        //获取allowances
        const allowance = await ercContract.allowance(address, pledgeContractAddress);

        const allowances = BigNumberToString(allowance, 18)

        const amount = ethers.utils.parseUnits(`${balanceAllowance}`, 18);

        //如果已授权allowances小于质押余额 重新申请 approve
        if (Number(allowances) < Number(balanceAllowance)) {
            const approveTx = await ercContract.connect(provider.getSigner()).approve(pledgeContractAddress, amount)
            console.log(approveTx);
        }

        const signer = provider.getSigner();
        //连接staking合约方法
        const stakingContract = new ethers.Contract(pledgeContractAddress, staking, signer);

        //防止approve未上链 阻塞10秒后stake
        await request(1000 * 13)
        console.log(pond,'质押的池子');
        //质押对应池
        const res = await stakingContract.stake(pond, amount);
        console.log(res);
        await request(1000 * 13)
        return res
    } catch (error) {
        console.log(error);
    }
}

/**
 * @阻塞
 */
export const request = (time) => {
    return new Promise(function (resolve, reject) {
        setTimeout(() => {
            resolve()
        }, time)
    })
}


export async function connectKeplr(_this) {
    // if (!window.getOfflineSigner || !window.keplr) {
    //   this.$notify({
    //     group: 'foo',
    //     title: 'Please install keplr extension',

    //     // text: 'Please install keplr extension',
    //     type: 'warn', // error //warn
    //     ///
    //   })
    // } else if (window.keplr.experimentalSuggestChain) {
    //   const Prefix = 'lamb'
    //   try {
    //     window.keplr.experimentalSuggestChain({
    //       chainId: lambconfig.defaultChainID,
    //       chainName: 'Lambda test',

    //       rpc: lambchainconfig[lambconfig.defaultChainID].rpc,
    //       rest: lambchainconfig[lambconfig.defaultChainID].rest,

    //       bip44: {
    //         coinType: 118,
    //       },
    //       bech32Config: {
    //         bech32PrefixAccAddr: Prefix,
    //         bech32PrefixAccPub: `${Prefix}pub`,
    //         bech32PrefixValAddr: `${Prefix}valoper`,
    //         bech32PrefixValPub: `${Prefix}valoperpub`,
    //         bech32PrefixConsAddr: `${Prefix}valcons`,
    //         bech32PrefixConsPub: `${Prefix}valconspub`,
    //       },
    //       currencies: [
    //         {
    //           coinDenom: 'LAMB',
    //           coinMinimalDenom: 'ulamb',
    //           coinDecimals: 18,
    //           coinGeckoId: 'lambda',
    //         },
    //       ],
    //       feeCurrencies: [
    //         {
    //           coinDenom: 'LAMB',
    //           coinMinimalDenom: 'ulamb',
    //           coinDecimals: 18,
    //           coinGeckoId: 'lambda',
    //         },
    //       ],
    //       stakeCurrency: { 
    //         coinDenom: "LAMB", 
    //         coinMinimalDenom: "ulamb", 
    //         coinDecimals: 18, 
    //         coinGeckoId: "lambda", 
    //     },
    //     gasPriceStep: {
    //         low: 25000000000,
    //         average: 25000000000,
    //         high: 40000000000,
    //     },
    //       features: ['ibc-transfer', 'ibc-go', 'eth-address-gen', 'eth-key-sign'],
    //     })
    //     const chainId = 'lambdatest_92001-1'
    //     await window.keplr.enable(chainId)
    //     const offlineSigner = window.getOfflineSigner(chainId)
    //     const accounts = await offlineSigner.getAccounts()
    //     console.log('accounts', accounts)
    //     const account = accounts[0].address
    //     let { pubkey } = accounts[0]
    //     const arrtoBuffer = toBuffer(pubkey)
    //     pubkey = arrtoBuffer.toString('base64')
    //     console.log(arrtoBuffer.toString('base64'))

    //     _this.$store.commit('changeCosmosAccount', account)
    //     _this.$store.commit('changeCosmospubkey', pubkey)

    //     Cookies.set('Keplrlink', '1')


    //   } catch (error) {
    //     console.log(error)

    //   }
    // } else {
    //   alert('Please use the recent version of keplr extension')
    // }
}
